﻿/*
   Copyright [yyyy] [name of copyright owner: NG tech.]
 
  Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
 */



using System;
using System.Collections.Generic;
using System.Xml;
using System.Xml.Serialization;
using System.IO;

//Библиотека классов сериализующих S-Гиперсеть

namespace SHNXml
{
    public class Node
    {
        [XmlAttribute("Name")]
        public String Name { get; set; }

        [XmlAttribute("X")]
        public Double X { get; set; }

        [XmlAttribute("Y")]
        public Double Y { get; set; }

        [XmlAttribute("Marker")]
        public Byte Marker { get; set; }

        [XmlAttribute("Priority")]
        public Byte priority { get; set; }

        [XmlAttribute("Color")]
        public String Color { get; set; }

        [XmlAttribute("Radius")]
        public Double Radius { get; set; }

        [XmlAttribute("LineType")]
        public int LineType { get; set; }

        [XmlAttribute("Parent")]
        public String Parent { get; set; }

		[XmlAttribute("Children")]
        public String Children { get; set; }

        /// <summary>
        /// Create new object
        /// </summary>
        public Node()
        {
            Name = String.Empty;
            Parent = String.Empty;
            Children = String.Empty;
            Color = "Black";
        }

        /// <summary>
        /// Create new object by <see cref="SHN.INode"/>
        /// </summary>
        /// <param name="Nodes">Reference on <see cref="SHN.INode"/></param>
        /// <exception cref="ArgumentException">Throw when Nodes = null</exception>
        public Node(SHN.INode Nodes)
        {
            if (Nodes == null) throw new System.ArgumentException("Parameter cannot be null", "Nodes");
            Name = Nodes.Name;
            X = Nodes.X;
            Y = Nodes.Y;
            Marker = Nodes.Marker;
            priority = Nodes.Priority;
            Color = Nodes.Color.Name;
            Radius = Nodes.Radius;
            LineType = (int)Nodes.LineType;
            try
            {
                Parent = Nodes.Parent.Name;
            }
            catch
            {
                Parent = "";
            }
			try
			{
				foreach (SHN.INetElement el in (Nodes as SHN.Node).ChildEdgelist)
				{
					Children += el.Name;
					Children += ";";
				}
			}
			catch
			{
				Children= "";
			}
        }
    }

  
    public class Edge //Сериализация ребра
    {
        [XmlAttribute("Name")]
        public String Name { get; set; }

        [XmlAttribute("InName")]
        public String InName { get; set; }

        [XmlAttribute("OutName")]
        public String OutName { get; set; }

        [XmlAttribute("Weight")]
        public Double Weight { get; set; }

        [XmlAttribute("Interval")]
        public String Interval { get; set; }

        [XmlAttribute("Color")]
        public String Color { get; set; }

		[XmlAttribute("LineType")]
        public int LineType { get; set; }

        [XmlAttribute("Parent")]
        public String Parents { get; set; }

        [XmlAttribute("Width")]
        public double Width { get; set; }

        [XmlAttribute("Capacity")]
        public Int32 Capacity { get; set; }

        public Edge()
        {
            Name = String.Empty;
            InName = String.Empty;
            OutName = String.Empty;
            Color = "Black";
            Parents = String.Empty;
        }

        /// <summary>
        /// Create new object by <see cref="SHN.IEdge"/>
        /// </summary>
        /// <param name="Edge">Reference on <see cref="SHN.IEdge"/></param>
        /// <exception cref="ArgumentException">Throw when Edge = null</exception>
        public Edge(SHN.IEdge Edge)
        {
            if (Edge == null) throw new System.ArgumentException("Parameter cannot be null", "Edge");
            Name = Edge.Name;
            InName = Edge.InName;
            OutName = Edge.OutName;
            Weight = Edge.Weight;
            Color = Edge.Color.Name;
			LineType = (int)Edge.LineType;
            Interval = Edge.Interval;
            Width = Edge.Width;
            Capacity = Edge.Capacity;
            try
            {
                foreach (SHN.INetElement el in Edge.Parents)
                {
                    Parents += el.Name;
                    Parents += ";";
                }
            }
            catch
            {
                Parents = "";
            }
        }

    }
	
	public class NetConfig
	{
		[XmlAttribute("NodeRadius")]
        public Double node_radius { get; set; }

		[XmlAttribute("NodeColor")]
        public String node_color { get; set; }

		[XmlAttribute("NodeLinetype")]
        public SHN.SHNLineTypes node_linetype { get; set; }

		[XmlAttribute("EdgeWidth")]
        public Double edge_width { get; set; }

		[XmlAttribute("EdgeColor")]
        public String edge_color { get; set; }

		[XmlAttribute("EdgeWeight")]
        public Double edge_weight { get; set; }

		[XmlAttribute("EdgeLinetype")]
        public SHN.SHNLineTypes edge_linetype { get; set; }

		public NetConfig() 
        {
            node_color = "Black";
            edge_color = "Black";
        }

        /// <summary>
        /// Create new object by <see cref="SHN.NetConfig"/>
        /// </summary>
        /// <param name="netconf">Reference on <see cref="SHN.NetConfig"/></param>
        /// <exception cref="ArgumentException">Throw when netconf = null</exception>
		public NetConfig(SHN.NetConfig netconf)
		{
            if (netconf == null) throw new System.ArgumentException("Parameter cannot be null", "netconf");
			node_radius = netconf.NodeRadius;
			node_color = netconf.NodeColor.Name;
			node_linetype = netconf.NodeLinetype;
			edge_width = netconf.EdgeWidth;
			edge_color = netconf.EdgeColor.Name;
			edge_linetype = netconf.EdgeLinetype;
			edge_weight = netconf.EdgeWeight;
		}
	}
   
    public interface Net
    {

    }
  
    public class SHyperNet:Net
    {
        [XmlAttribute("Name")]
        public String Name { get; set; }

        [XmlAttribute("Parent")]
        public String Parent { get; set; }

        [XmlArrayItem("Node", typeof(Node))]
        public List<Node> Nodes { get; set; }

        [XmlArrayItem("Edge", typeof(Edge))]
        public List<Edge> Edges { get; set; }

		[XmlElement("NetConfig", typeof(NetConfig))]
        public NetConfig netconf { get; set; }

        [XmlArrayItem("NestNets", typeof(SHyperNet))]
        public List<SHyperNet> NestNet { get; set; }

        public SHyperNet()
        {
            Nodes = new List<Node>();
            Edges = new List<Edge>();
            Parent = String.Empty;
            Name = String.Empty;
            netconf = new NetConfig();
            NestNet = new List<SHyperNet>();
        }

        /// <summary>
        /// Create new object by <see cref="SHN.SHyperNet"/>
        /// </summary>
        /// <param name="sn">Reference on <see cref="SHN.SHyperNet"/>, cannot be null</param>
        /// <exception cref="ArgumentException">Throw when sn = null</exception>
        public SHyperNet(SHN.SHyperNet sn)
        {
            //if (netconf == null) throw new System.ArgumentException("Parameter cannot be null", "sn"); - хз че это за херна, но с ней ничего не работает.
			if (sn == null) throw new System.ArgumentException("Parameter cannot be null", "sn");
            Name = sn.Name;
            try
            {
                Parent = sn.Parent.Name;
            }
            catch
            {
                Parent = "";
            }
            Nodes = new List<Node>();
            for (Int32 i = 0; i < sn.CountNode; i++)
            {
                try
                {
                    Node temp;
                    temp = new Node((SHN.Node)sn.GetNode(i));
                    Nodes.Add(temp);
                }
                catch (System.ArgumentException e)
                {
                    if (e.ParamName == "i") throw e;
                }
            }
            Edges = new List<Edge>();
            for (Int32 i = 0; i < sn.CountEdge; i++)
            {
                try
                {
                    Edge temp;
                    temp = new Edge(sn.GetEdge(i));
                    Edges.Add(temp);
                }
                catch (System.ArgumentException e)
                {
                    if (e.ParamName == "i") throw e;
                }
                
            }
			netconf = new NetConfig(sn.CurrentNetConfig);
			
            NestNet = new List<SHyperNet>();
            for (Int32 i = 0; i < sn.NestNets.Count; i++)
            {
                try
                {
                    NestNet.Add(new SHyperNet(sn.NestNets[i] as SHN.SHyperNet));
                }
                catch (System.ArgumentException e) { }
            }


            /*
            NestNet = new List<Net>();
            for (Int32 i = 0; i < sn.NestNets.Count; i++)
            {
                if (sn.NestNets[i] is SHNClasses.SecondNet)
                {
                    SHNClasses.SecondNet t = (SHNClasses.SecondNet)sn.NestNets[i];
                    SecondNet s = new SecondNet(t);
                    NestNet.Add(s);
                }
                if (sn.NestNets[i] is SHNClasses.SHyperNet)
                {
                    SHNClasses.SHyperNet t = (SHNClasses.SHyperNet)sn.NestNets[i];
                    SHyperNet s = new SHyperNet(t);
                    NestNet.Add(s);
                }
            }*/

        }

        public void SaveToXml(String filename)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(SHyperNet));
            using (StreamWriter writer = new StreamWriter(filename))
            {
                serializer.Serialize(writer, this);
            }
        }

        /// <summary>
        /// Serialize object from xml file
        /// </summary>
        /// <param name="filename"></param>
        /// <returns><see cref="SHyperNet"/></returns>
        /// <exception cref="ArgumentException"></exception>
        static public SHyperNet LoadToXml(String filename)   //Загрузка
        {
            XmlSerializer serializer = new XmlSerializer(typeof(SHyperNet));
            using (StreamReader reader = new StreamReader(filename))
            {
                try
                {
                    SHyperNet temp;
                    temp = new SHyperNet();
                    temp = (SHyperNet)serializer.Deserialize(reader);
                    return temp;
                }
                catch(System.InvalidOperationException ex)
                {
                    throw new System.ArgumentException("Failed serialize from file", "filename", ex);
                }
               
            };
        } 
    }

}
